#coding: utf-8

from lib.common import AbstractHandler
from django.http import JsonResponse
from lib.sms import sender
from ratelimit.decorators import ratelimit

from services.datamodel.publishers.models import Publisher
from services.datamodel.utils import Utils
import logging,traceback
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from services.datamodel.share import BusinessCode
from services.datamodel.student.models import Student
from services.datamodel.parent.models import Parent
from services.datamodel.teacher.models import Teacher
from services.datamodel.proxy.models import Proxy


class PasswordHandler(AbstractHandler):

    USER_DATA_CLASS = {
        'student': Student,
        'teacher': Teacher,
        'parent': Parent,
        'proxy': Proxy,
        'publisher': Publisher
    }
    
    def __init__(self):
        AbstractHandler.__init__(self,logging.getLogger("sms"))
        self.METHOD_TAB = {
            'GET': {
                'get_reset_password_sms': self.getForgetPasswordSMS,
                'get_user_phone': self.getUserPhone,
            },
            'POST': {
                'reset_password': self.resetPassword
            }
        }

    @ratelimit(key='get:username', rate='1/m')
    @ratelimit(key='ip', rate='500/d')
    def getForgetPasswordSMS(self, request):
        self.checkMandatoryParams(request, ['username', 'user_type'])
        self.param_in_options(request, 'user_type', self.USER_DATA_CLASS.keys())
        user_type = request.param_dict['user_type']
        username = request.param_dict['username']
        if getattr(request, 'limited', False):
            return JsonResponse({'retcode': 1, 'msg': '操作过快, 稍后再试'})
        userInfo = Utils.findUserByName(username, self.USER_DATA_CLASS[user_type])
        if not userInfo[0] or not userInfo[0].phonenumber:
            return JsonResponse({
                'retcode': 1,
                'msg': "用户名不存在或未绑定手机号"
            })

        target = userInfo[0].phonenumber
        ret = sender.sendcode(BusinessCode.FORGETPASSWORD, target)

        return JsonResponse(ret)

    @csrf_exempt
    #@ratelimit(key='get:username',rate='1/m')
    #@ratelimit(key='ip', rate='500/d')
    def resetPassword(self, request):
        self.checkMandatoryParams(request, ['username', 'smscode', 'password', 'user_type'])
        self.param_in_options(request, 'user_type', self.USER_DATA_CLASS.keys())
        user_type = request.param_dict['user_type']
        username = request.param_dict['username']
        smscode = request.param_dict['smscode']
        password = request.param_dict['password']

        if getattr(request, 'limited', False):
            return JsonResponse({'retcode':1,'msg':'操作过快, 稍后再试'})
        # check user
        userInfo = Utils.findUserByName(username, self.USER_DATA_CLASS[user_type])
        if not userInfo[0] or not userInfo[0].phonenumber:
            return JsonResponse({
                'retcode': 1,
                'msg': "用户名不存在: `%s`" % username
            })

        # check sms code
        target = userInfo[0].phonenumber
        smsRet = sender.checkcode(BusinessCode.FORGETPASSWORD, target, smscode)

        if smsRet['retcode']:
            return JsonResponse(smsRet)

        # reset password
        try:
            usr = userInfo[0].user
            usr.set_password(password)
            usr.save()
        except:
            err = traceback.format_exc()
            return JsonResponse({'retcode':1, 'msg':err})

        return JsonResponse({'retcode':0, 'msg':''})

    @ratelimit(key='ip', rate='1/10s')
    def getUserPhone(self, request):
        """
        Request sample:
            curl http://127.0.0.1:8000/api/utils/password/get_user_phone/?username=nj
        :param request:
        :return:
        """
        self.checkMandatoryParams(request, ['username', 'user_type'])
        self.param_in_options(request, 'user_type', self.USER_DATA_CLASS.keys())
        user_type = request.param_dict['user_type']
        username = request.param_dict['username']
        if getattr(request, 'limited', False):
            return JsonResponse({'retcode': settings.RATELIMITTED_CODE, 'msg': '操作频繁, 请稍后再试'})
        userInfo = Utils.findUserByName(username, self.USER_DATA_CLASS[user_type])
        if not userInfo[0] or not userInfo[0].phonenumber:
            return JsonResponse({
                'retcode': 1,
                'msg': "用户名不存在或未绑定手机号"
            })
        phone = userInfo[0].phonenumber
        cell = phone[:3]+'*'*5+phone[-3:]
        return JsonResponse({'retcode':0,'phone':cell})


    # @ratelimit(key='ip',rate='1/m')
    # def getBulkSMSCode(self,request):
    #     for param in ['phonelist']:
    #         if param not in request.REQUEST:
    #             return JsonResponse({
    #                 'retcode': 1,
    #                 'msg': u"没有手机号"
    #             })
    #     if getattr(request, 'limited', False):
    #         return JsonResponse({'retcode':1,'msg':'操作过快, 稍后再试'})
    #
    #     try:
    #         phonelist = request.REQUEST.get('phonelist', '[]')
    #         phonelist = json.loads(phonelist)
    #         MAX_PHONES_PER_REQ = 6
    #         if len(phonelist) >= MAX_PHONES_PER_REQ or len(phonelist) == 0:
    #             return JsonResponse({
    #                 'retcode': 1,
    #                 'msg': u"手机号太多"
    #             })
    #
    #         ret = {'retcode': 0, 'msg': ''}
    #         for target in phonelist:
    #             sign = Utils.calcSign(str(target))
    #             smsRet = sender.sendcode(BusinessCode.BULK_SMS,str(target),sign)
    #             if smsRet['retcode']:
    #                 ret = smsRet
    #                 break
    #
    #         return JsonResponse(ret)
    #     except:
    #         err = traceback.format_exc()
    #         return JsonResponse({'retcode':1, 'msg':err})
    #
    # @ratelimit(key='ip',rate='3/3m')
    # def getSMSWithBC(self,request):
    #     '''
    #     http://127.0.0.1:8000/api/utils/password/get_sms_with_bc/?bc=xx&phone=xx
    #     :param request:
    #     :return:
    #     '''
    #     # self.checkMandatoryParams(request,['bc', 'phone','invitecode'])
    #     for param in ['bc', 'phone', 'invitecode']:
    #         if param not in request.REQUEST:
    #             return JsonResponse({
    #                 'retcode': 1,
    #                 'msg': u"缺少必要参数: %s" % param
    #             })
    #
    #     if getattr(request, 'limited', False):
    #         return JsonResponse({'retcode':1,'msg':'操作过快, 稍后再试'})
    #
    #     invitecode=request.REQUEST['invitecode']
    #     if not Class.objects.filter(invitecode=invitecode).exists():
    #         return JsonResponse({'retcode':2,'msg':u'您输入的班级邀请码 %s 不存在' % invitecode})
    #
    #     try:
    #         phone = request.REQUEST['phone']
    #         bc = request.REQUEST['bc']
    #         ret = {'retcode': 0, 'msg': ''}
    #         sign = Utils.calcSign(str(phone))
    #         smsRet = sender.sendcode(bc.upper(), str(phone), sign)
    #         if smsRet['retcode']:
    #             ret = smsRet
    #
    #         return JsonResponse(ret)
    #     except:
    #         err = traceback.format_exc()
    #         return JsonResponse({'retcode':1, 'msg':err})

handler = PasswordHandler()
